/*     */ package com.zimbra.cs.session;
/*     */ 
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.MailboxManager;
/*     */ import com.zimbra.cs.mailbox.MailboxManager.FetchMode;
/*     */ import com.zimbra.cs.mailbox.MailboxManager.Listener;
/*     */ import com.zimbra.cs.service.mail.WaitSetRequest;
/*     */ import com.zimbra.cs.service.util.SyncToken;
/*     */ import java.util.ArrayList;
/*     */ import java.util.HashMap;
/*     */ import java.util.HashSet;
/*     */ import java.util.LinkedList;
/*     */ import java.util.List;
/*     */ import java.util.Map.Entry;
/*     */ import java.util.Set;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class SomeAccountsWaitSet
/*     */   extends WaitSetBase
/*     */   implements MailboxManager.Listener
/*     */ {
/*     */   SomeAccountsWaitSet(String ownerAccountId, String id, Set<MailItem.Type> defaultInterest)
/*     */   {
/*  48 */     super(ownerAccountId, id, defaultInterest);
/*  49 */     this.mCurrentSeqNo = 1L;
/*     */   }
/*     */   
/*     */   public List<WaitSetError> removeAccounts(List<String> accts)
/*     */   {
/*  54 */     List<WaitSetError> errors = new ArrayList();
/*     */     
/*  56 */     for (String id : accts) {
/*  57 */       WaitSetSession session = null;
/*  58 */       synchronized (this) {
/*  59 */         WaitSetAccount wsa = (WaitSetAccount)this.mSessions.get(id);
/*  60 */         if (wsa != null) {
/*  61 */           session = wsa.getSession();
/*  62 */           this.mSessions.remove(id);
/*     */         } else {
/*  64 */           errors.add(new WaitSetError(id, WaitSetError.Type.NOT_IN_SET_DURING_REMOVE));
/*     */         }
/*     */       }
/*  67 */       if (session != null) {
/*  68 */         assert (!Thread.holdsLock(this));
/*  69 */         session.doCleanup();
/*     */       }
/*     */     }
/*  72 */     return errors;
/*     */   }
/*     */   
/*     */ 
/*     */   public synchronized List<WaitSetError> doWait(WaitSetCallback cb, String lastKnownSeqNo, List<WaitSetAccount> addAccounts, List<WaitSetAccount> updateAccounts)
/*     */     throws ServiceException
/*     */   {
/*  79 */     cancelExistingCB();
/*     */     
/*  81 */     List<WaitSetError> errors = new LinkedList();
/*     */     
/*  83 */     if (addAccounts != null) {
/*  84 */       errors.addAll(addAccounts(addAccounts));
/*     */     }
/*  86 */     if (updateAccounts != null) {
/*  87 */       errors.addAll(updateAccounts(updateAccounts));
/*     */     }
/*     */     
/*  90 */     this.mCb = cb;
/*  91 */     this.mCbSeqNo = Long.parseLong(lastKnownSeqNo);
/*  92 */     trySendData();
/*     */     
/*  94 */     return errors;
/*     */   }
/*     */   
/*     */   public void mailboxAvailable(Mailbox mbox)
/*     */   {
/*  99 */     mailboxLoaded(mbox);
/*     */   }
/*     */   
/*     */   public void mailboxCreated(Mailbox mbox)
/*     */   {
/* 104 */     mailboxLoaded(mbox);
/*     */   }
/*     */   
/*     */   public synchronized void mailboxLoaded(Mailbox mbox)
/*     */   {
/* 109 */     WaitSetAccount wsa = (WaitSetAccount)this.mSessions.get(mbox.getAccountId());
/* 110 */     if (wsa != null)
/*     */     {
/* 112 */       WaitSetError error = initializeWaitSetSession(wsa, mbox);
/* 113 */       if (error != null) {
/* 114 */         this.mSessions.remove(wsa.getAccountId());
/* 115 */         signalError(error);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   public synchronized void mailboxDeleted(String accountId)
/*     */   {
/* 122 */     WaitSetAccount wsa = (WaitSetAccount)this.mSessions.get(accountId);
/* 123 */     if (wsa != null) {
/* 124 */       this.mSessions.remove(accountId);
/* 125 */       signalError(new WaitSetError(accountId, WaitSetError.Type.MAILBOX_DELETED));
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   private synchronized WaitSetError initializeWaitSetSession(WaitSetAccount wsa, Mailbox mbox)
/*     */   {
/* 133 */     WaitSetSession session = wsa.getSession();
/* 134 */     if ((session != null) && (session.getMailbox() != mbox)) {
/* 135 */       ZimbraLog.session.warn("SESSION BEING LEAKED? WaitSetSession points to old version of mailbox...possibly leaking this session:", new Object[] { session });
/* 136 */       wsa.cleanupSession();
/* 137 */       session = null;
/*     */     }
/*     */     
/* 140 */     if (session == null) {
/* 141 */       return wsa.createSession(mbox, this);
/*     */     }
/* 143 */     return null;
/*     */   }
/*     */   
/*     */ 
/*     */   protected boolean cbSeqIsCurrent()
/*     */   {
/* 149 */     return this.mCbSeqNo == this.mCurrentSeqNo;
/*     */   }
/*     */   
/*     */   protected String toNextSeqNo()
/*     */   {
/* 154 */     this.mCurrentSeqNo += 1L;
/* 155 */     return Long.toString(this.mCurrentSeqNo);
/*     */   }
/*     */   
/*     */   private synchronized List<WaitSetError> updateAccounts(List<WaitSetAccount> updates) {
/* 159 */     List<WaitSetError> errors = new ArrayList();
/*     */     
/* 161 */     for (WaitSetAccount update : updates) {
/* 162 */       WaitSetAccount existing = (WaitSetAccount)this.mSessions.get(update.getAccountId());
/* 163 */       if (existing != null) {
/* 164 */         existing.setInterests(update.getInterests());
/* 165 */         existing.setLastKnownSyncToken(update.getLastKnownSyncToken());
/* 166 */         WaitSetSession session = existing.getSession();
/* 167 */         if (session != null) {
/* 168 */           session.update(existing.getInterests(), existing.getLastKnownSyncToken());
/*     */         }
/*     */       }
/*     */       else {
/* 172 */         errors.add(new WaitSetError(update.getAccountId(), WaitSetError.Type.NOT_IN_SET_DURING_UPDATE));
/*     */       }
/*     */     }
/* 175 */     return errors;
/*     */   }
/*     */   
/*     */   synchronized List<WaitSetError> addAccounts(List<WaitSetAccount> wsas) {
/* 179 */     List<WaitSetError> errors = new ArrayList();
/*     */     
/* 181 */     for (WaitSetAccount wsa : wsas) {
/* 182 */       if (!this.mSessions.containsKey(wsa.getAccountId()))
/*     */       {
/* 184 */         this.mSessions.put(wsa.getAccountId(), wsa);
/*     */         
/*     */ 
/*     */ 
/*     */ 
/*     */         try
/*     */         {
/* 191 */           MailboxManager.FetchMode fetchMode = MailboxManager.FetchMode.AUTOCREATE;
/* 192 */           if (wsa.getLastKnownSyncToken() == null) {
/* 193 */             fetchMode = MailboxManager.FetchMode.ONLY_IF_CACHED;
/*     */           }
/*     */           
/*     */ 
/*     */ 
/* 198 */           Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(wsa.getAccountId(), fetchMode);
/* 199 */           if (mbox != null) {
/* 200 */             WaitSetError error = initializeWaitSetSession(wsa, mbox);
/* 201 */             if (error != null) {
/* 202 */               errors.add(error);
/*     */             }
/*     */           }
/*     */         } catch (ServiceException e) {
/* 206 */           if (e.getCode() == "account.NO_SUCH_ACCOUNT") {
/* 207 */             errors.add(new WaitSetError(wsa.getAccountId(), WaitSetError.Type.NO_SUCH_ACCOUNT));
/* 208 */           } else if (e.getCode() == "service.WRONG_HOST") {
/* 209 */             errors.add(new WaitSetError(wsa.getAccountId(), WaitSetError.Type.WRONG_HOST_FOR_ACCOUNT));
/*     */           } else {
/* 211 */             errors.add(new WaitSetError(wsa.getAccountId(), WaitSetError.Type.ERROR_LOADING_MAILBOX));
/*     */           }
/* 213 */           this.mSessions.remove(wsa);
/*     */         }
/*     */       }
/*     */       else {
/* 217 */         errors.add(new WaitSetError(wsa.getAccountId(), WaitSetError.Type.ALREADY_IN_SET_DURING_ADD));
/*     */       }
/*     */     }
/* 220 */     return errors;
/*     */   }
/*     */   
/*     */   synchronized void cleanupSession(WaitSetSession session) {
/* 224 */     WaitSetAccount acct = (WaitSetAccount)this.mSessions.get(session.getAuthenticatedAccountId());
/* 225 */     if (acct != null) {
/* 226 */       acct.cleanupSession();
/*     */     }
/*     */   }
/*     */   
/*     */   int countSessions()
/*     */   {
/* 232 */     return this.mSessions.size();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   synchronized HashMap<String, WaitSetAccount> destroy()
/*     */   {
/*     */     try
/*     */     {
/* 241 */       MailboxManager.getInstance().removeListener(this);
/*     */     } catch (ServiceException e) {
/* 243 */       ZimbraLog.session.warn("Caught unexpected ServiceException while destroying WaitSet: " + e, e);
/*     */     }
/* 245 */     cancelExistingCB();
/* 246 */     HashMap<String, WaitSetAccount> toRet = this.mSessions;
/* 247 */     this.mSessions = new HashMap();
/* 248 */     this.mCurrentSignalledSessions.clear();
/* 249 */     this.mSentSignalledSessions.clear();
/* 250 */     this.mCurrentSeqNo = Long.MAX_VALUE;
/* 251 */     return toRet;
/*     */   }
/*     */   
/*     */   WaitSetCallback getCb()
/*     */   {
/* 256 */     return this.mCb;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   synchronized void unsignalDataReady(WaitSetSession session)
/*     */   {
/* 267 */     if (this.mSessions.containsKey(session.getAuthenticatedAccountId())) {
/* 268 */       this.mCurrentSignalledSessions.remove(session.getAuthenticatedAccountId());
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   synchronized void signalDataReady(WaitSetSession session)
/*     */   {
/* 278 */     boolean trace = ZimbraLog.session.isTraceEnabled();
/* 279 */     if (trace) ZimbraLog.session.trace("SomeAccountsWaitSet.signalDataReady 1");
/* 280 */     if (this.mSessions.containsKey(session.getAuthenticatedAccountId())) {
/* 281 */       if (trace) ZimbraLog.session.trace("SomeAccountsWaitSet.signalDataReady 2");
/* 282 */       if (this.mCurrentSignalledSessions.add(session.getAuthenticatedAccountId())) {
/* 283 */         if (trace) ZimbraLog.session.trace("SomeAccountsWaitSet.signalDataReady 3");
/* 284 */         trySendData();
/*     */       }
/*     */     }
/* 287 */     if (trace) ZimbraLog.session.trace("SomeAccountsWaitSet.signalDataReady done");
/*     */   }
/*     */   
/*     */   public synchronized void handleQuery(Element response)
/*     */   {
/* 292 */     super.handleQuery(response);
/*     */     
/* 294 */     response.addAttribute("cbSeqNo", this.mCbSeqNo);
/* 295 */     response.addAttribute("currentSeqNo", this.mCurrentSeqNo);
/*     */     
/* 297 */     for (Map.Entry<String, WaitSetAccount> entry : this.mSessions.entrySet()) {
/* 298 */       Element sessionElt = response.addElement("session");
/* 299 */       WaitSetAccount wsa = (WaitSetAccount)entry.getValue();
/*     */       
/* 301 */       assert (wsa.getAccountId().equals(entry.getKey()));
/* 302 */       if (!wsa.getAccountId().equals(entry.getKey())) {
/* 303 */         sessionElt.addAttribute("acctIdError", wsa.getAccountId());
/*     */       }
/*     */       
/* 306 */       sessionElt.addAttribute("account", (String)entry.getKey());
/* 307 */       sessionElt.addAttribute("types", WaitSetRequest.expandInterestStr(wsa.getInterests()));
/*     */       
/* 309 */       if (wsa.getLastKnownSyncToken() != null) {
/* 310 */         sessionElt.addAttribute("token", wsa.getLastKnownSyncToken().toString());
/*     */       }
/*     */       
/* 313 */       if (wsa.getLastKnownSyncToken() != null) {
/*     */         try {
/* 315 */           Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(wsa.getAccountId(), MailboxManager.FetchMode.ONLY_IF_CACHED);
/* 316 */           if (mbox != null) {
/* 317 */             int mboxLastChange = mbox.getLastChangeID();
/* 318 */             sessionElt.addAttribute("mboxSyncToken", mboxLastChange);
/* 319 */             sessionElt.addAttribute("mboxSyncTokenDiff", mboxLastChange - wsa.getLastKnownSyncToken().getChangeId());
/*     */           }
/*     */         } catch (Exception e) {
/* 322 */           ZimbraLog.session.warn("Caught exception from MailboxManager in SomeAccountsWaitSet.handleQuery() for accountId" + wsa.getAccountId(), e);
/*     */         }
/*     */       }
/*     */       
/*     */ 
/* 327 */       WaitSetSession wss = wsa.getSession();
/* 328 */       if (wss != null) {
/* 329 */         Element wssElt = sessionElt.addElement("WaitSetSession");
/* 330 */         wssElt.addAttribute("interestMask", WaitSetRequest.interestToStr(wss.interest));
/* 331 */         wssElt.addAttribute("highestChangeId", wss.mHighestChangeId);
/* 332 */         wssElt.addAttribute("lastAccessTime", wss.getLastAccessTime());
/* 333 */         wssElt.addAttribute("creationTime", wss.getCreationTime());
/* 334 */         wssElt.addAttribute("sessionId", wss.getSessionId());
/*     */         
/* 336 */         if (wss.mSyncToken != null) {
/* 337 */           wssElt.addAttribute("token", wss.mSyncToken.toString());
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/* 343 */   private long mCbSeqNo = 0L;
/*     */   
/*     */   private long mCurrentSeqNo;
/*     */   
/* 347 */   private HashMap<String, WaitSetAccount> mSessions = new HashMap();
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/session/SomeAccountsWaitSet.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */